Removes redundant/unnecessary __vmread/__vmwrite.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 21 Sep 2005 10:11:02 +0000 (10:11 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 21 Sep 2005 10:11:02 +0000 (10:11 +0000)
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
xen/arch/x86/vmx.c
xen/arch/x86/vmx_io.c
xen/arch/x86/vmx_vmcs.c
xen/include/asm-x86/vmx.h
xen/include/asm-x86/vmx_vmcs.h

index da1016cf92aec650d76107028a5c13dd6cf626cf..bb4d9cf94237dbca0693306002e6039c660c0198 100644 (file)
@@ -377,12 +377,13 @@ static void inline __update_guest_eip(unsigned long inst_len)
 
 static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs) 
 {
-    unsigned long eip;
     unsigned long gpa; /* FIXME: PAE */
     int result;
 
-#if VMX_DEBUG
+#if 0 /* keep for debugging */
     {
+        unsigned long eip;
+
         __vmread(GUEST_RIP, &eip);
         VMX_DBG_LOG(DBG_LEVEL_VMMU, 
                     "vmx_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
@@ -429,9 +430,9 @@ static void vmx_do_no_device_fault(void)
         
     clts();
     setup_fpu(current);
-    __vmread(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
     if (!(cr0 & X86_CR0_TS)) {
-        __vmread(GUEST_CR0, &cr0);
+        __vmread_vcpu(GUEST_CR0, &cr0);
         cr0 &= ~X86_CR0_TS;
         __vmwrite(GUEST_CR0, cr0);
     }
@@ -1129,9 +1130,7 @@ static int vmx_set_cr0(unsigned long value)
                 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
             }
         }
-        __vmread(GUEST_RIP, &eip);
-        VMX_DBG_LOG(DBG_LEVEL_1,
-                    "Disabling CR0.PE at %%eip 0x%lx\n", eip);
+
         if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
             set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state);
             __vmread(GUEST_RIP, &eip);
@@ -1370,17 +1369,17 @@ static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs
         clts();
         setup_fpu(current);
 
-        __vmread(GUEST_CR0, &value);
+        __vmread_vcpu(GUEST_CR0, &value);
         value &= ~X86_CR0_TS; /* clear TS */
         __vmwrite(GUEST_CR0, value);
 
-        __vmread(CR0_READ_SHADOW, &value);
+        __vmread_vcpu(CR0_READ_SHADOW, &value);
         value &= ~X86_CR0_TS; /* clear TS */
         __vmwrite(CR0_READ_SHADOW, value);
         break;
     case TYPE_LMSW:
         TRACE_VMEXIT(1,TYPE_LMSW);
-        __vmread(CR0_READ_SHADOW, &value);
+        __vmread_vcpu(CR0_READ_SHADOW, &value);
         value = (value & ~0xF) |
             (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
         return vmx_set_cr0(value);
@@ -1456,16 +1455,12 @@ static inline void vmx_do_msr_write(struct cpu_user_regs *regs)
                 (unsigned long)regs->edx);
 }
 
+volatile unsigned long do_hlt_count;
 /*
  * Need to use this exit to reschedule
  */
-static inline void vmx_vmexit_do_hlt(void)
+void vmx_vmexit_do_hlt(void)
 {
-#if VMX_DEBUG
-    unsigned long eip;
-    __vmread(GUEST_RIP, &eip);
-#endif
-    VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_hlt:eip=%lx", eip);
     raise_softirq(SCHEDULE_SOFTIRQ);
 }
 
@@ -1516,13 +1511,9 @@ static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
     }
 }
 
+volatile unsigned long do_mwait_count;
 static inline void vmx_vmexit_do_mwait(void)
 {
-#if VMX_DEBUG
-    unsigned long eip;
-    __vmread(GUEST_RIP, &eip);
-#endif
-    VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_mwait:eip=%lx", eip);
     raise_softirq(SCHEDULE_SOFTIRQ);
 }
 
@@ -1631,9 +1622,13 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
         return;
     }
 
-    __vmread(GUEST_RIP, &eip);
-    TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
-    TRACE_VMEXIT(0,exit_reason);
+#ifdef TRACE_BUFFER
+    {
+        __vmread(GUEST_RIP, &eip);
+        TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
+        TRACE_VMEXIT(0,exit_reason);
+    }
+#endif
 
     switch (exit_reason) {
     case EXIT_REASON_EXCEPTION_NMI:
index f0a5357b31140c8bc67e4ee998be28b651ba2f6d..4ad3ae8dc7411bace3f1a97a763c9cc641b565a8 100644 (file)
@@ -891,7 +891,7 @@ asmlinkage void vmx_intr_assist(void)
     struct vcpu *v = current;
 
     highest_vector = find_highest_pending_irq(v, &intr_type);
-    __vmread(CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
+    __vmread_vcpu(CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
 
     if (highest_vector == -1) {
         disable_irq_window(cpu_exec_control);
@@ -948,14 +948,6 @@ asmlinkage void vmx_intr_assist(void)
 void vmx_do_resume(struct vcpu *d) 
 {
     vmx_stts();
-    if ( vmx_paging_enabled(d) )
-        __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
-    else
-        // paging is not enabled in the guest
-        __vmwrite(GUEST_CR3, pagetable_get_paddr(d->domain->arch.phys_table));
-
-    __vmwrite(HOST_CR3, pagetable_get_paddr(d->arch.monitor_table));
-    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
 
     if (event_pending(d)) {
         vmx_check_events(d);
index 85baa632bcebf3cc674bb4cb20a570778f233f04..70d94e63712a4d67108ac0d693e7c0220a800865 100644 (file)
@@ -68,9 +68,6 @@ static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
     error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, 
                        MONITOR_PIN_BASED_EXEC_CONTROLS);
 
-    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, 
-                       MONITOR_CPU_BASED_EXEC_CONTROLS);
-
     error |= __vmwrite(VM_EXIT_CONTROLS, MONITOR_VM_EXIT_CONTROLS);
 
     error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
@@ -117,12 +114,6 @@ struct host_execution_env {
     unsigned long fs_base; 
     unsigned long gs_base; 
 #endif 
-
-    /* control registers */
-    unsigned long cr3;
-    unsigned long cr0;
-    unsigned long cr4;
-    unsigned long dr7;
 };
 
 #define round_pgdown(_p) ((_p)&PAGE_MASK) /* coped from domain.c */
@@ -217,9 +208,33 @@ void vmx_do_launch(struct vcpu *v)
 /* Update CR3, GDT, LDT, TR */
     unsigned int  error = 0;
     unsigned long pfn = 0;
+    unsigned long cr0, cr4;
     struct pfn_info *page;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
 
+    __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
+
+    error |= __vmwrite(GUEST_CR0, cr0);
+    cr0 &= ~X86_CR0_PG;
+    error |= __vmwrite(CR0_READ_SHADOW, cr0);
+    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, 
+                       MONITOR_CPU_BASED_EXEC_CONTROLS);
+
+    __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (cr4) : );
+
+#ifdef __x86_64__
+    error |= __vmwrite(GUEST_CR4, cr4 & ~X86_CR4_PSE);
+#else
+    error |= __vmwrite(GUEST_CR4, cr4);
+#endif
+
+#ifdef __x86_64__
+    cr4 &= ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
+#else
+    cr4 &= ~(X86_CR4_PGE | X86_CR4_VMXE);
+#endif
+    error |= __vmwrite(CR4_READ_SHADOW, cr4);
+
     vmx_stts();
 
     page = (struct pfn_info *) alloc_domheap_page(NULL);
@@ -254,7 +269,7 @@ construct_init_vmcs_guest(struct cpu_user_regs *regs,
     int error = 0;
     union vmcs_arbytes arbytes;
     unsigned long dr7;
-    unsigned long eflags, shadow_cr;
+    unsigned long eflags;
 
     /* MSR */
     error |= __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0);
@@ -326,27 +341,7 @@ construct_init_vmcs_guest(struct cpu_user_regs *regs,
 
     arbytes.fields.seg_type = 0xb;          /* 32-bit TSS (busy) */
     error |= __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
-
-    error |= __vmwrite(GUEST_CR0, host_env->cr0); /* same CR0 */
-
-    /* Initally PG, PE are not set*/
-    shadow_cr = host_env->cr0;
-    shadow_cr &= ~X86_CR0_PG;
-    error |= __vmwrite(CR0_READ_SHADOW, shadow_cr);
     /* CR3 is set in vmx_final_setup_guest */
-#ifdef __x86_64__
-    error |= __vmwrite(GUEST_CR4, host_env->cr4 & ~X86_CR4_PSE);
-#else
-    error |= __vmwrite(GUEST_CR4, host_env->cr4);
-#endif
-    shadow_cr = host_env->cr4;
-
-#ifdef __x86_64__
-    shadow_cr &= ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
-#else
-    shadow_cr &= ~(X86_CR4_PGE | X86_CR4_VMXE);
-#endif
-    error |= __vmwrite(CR4_READ_SHADOW, shadow_cr);
 
     error |= __vmwrite(GUEST_ES_BASE, host_env->ds_base);
     error |= __vmwrite(GUEST_CS_BASE, host_env->cs_base);
@@ -403,12 +398,10 @@ static inline int construct_vmcs_host(struct host_execution_env *host_env)
     host_env->cs_base = 0;
 
     __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (crn) : );
-    host_env->cr0 = crn;
     error |= __vmwrite(HOST_CR0, crn); /* same CR0 */
 
     /* CR3 is set in vmx_final_setup_hostos */
     __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (crn) : ); 
-    host_env->cr4 = crn;
     error |= __vmwrite(HOST_CR4, crn);
 
     error |= __vmwrite(HOST_RIP, (unsigned long) vmx_asm_vmexit_handler);
index 33b8dd21d87cd94bc1b01abb5491ad366e1cbdd6..fa2600e5bc7f79ba04dd89d672d2abf2cb586a20 100644 (file)
@@ -314,6 +314,57 @@ static always_inline int ___vmread (const unsigned long field,  void *ptr, const
     return 0;
 }
 
+
+static always_inline void __vmwrite_vcpu(unsigned long field, unsigned long value)
+{
+    struct vcpu *v = current;
+
+    switch(field) {
+    case CR0_READ_SHADOW:
+       v->arch.arch_vmx.cpu_shadow_cr0 = value;
+       break;
+    case GUEST_CR0:
+       v->arch.arch_vmx.cpu_cr0 = value;
+       break;
+    case CPU_BASED_VM_EXEC_CONTROL:
+       v->arch.arch_vmx.cpu_based_exec_control = value;
+       break;
+    default:
+       printk("__vmwrite_cpu: invalid field %lx\n", field);
+       break;
+    }
+}
+
+static always_inline void __vmread_vcpu(unsigned long field, unsigned long *value)
+{
+    struct vcpu *v = current;
+
+    switch(field) {
+    case CR0_READ_SHADOW:
+       *value = v->arch.arch_vmx.cpu_shadow_cr0;
+       break;
+    case GUEST_CR0:
+       *value = v->arch.arch_vmx.cpu_cr0;
+       break;
+    case CPU_BASED_VM_EXEC_CONTROL:
+       *value = v->arch.arch_vmx.cpu_based_exec_control;
+       break;
+    default:
+       printk("__vmread_cpu: invalid field %lx\n", field);
+       break;
+    }
+
+   /* 
+    * __vmwrite() can be used for non-current vcpu, and it's possible that
+    * the vcpu field is not initialized at that case.
+    * 
+    */
+    if (!*value) {
+       __vmread(field, value);
+       __vmwrite_vcpu(field, *value);
+    }
+}
+
 static inline int __vmwrite (unsigned long field, unsigned long value)
 {
     unsigned long eflags;
@@ -326,6 +377,15 @@ static inline int __vmwrite (unsigned long field, unsigned long value)
     __save_flags(eflags);
     if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF)
         return -1;
+
+    switch(field) {
+    case CR0_READ_SHADOW:
+    case GUEST_CR0:
+    case CPU_BASED_VM_EXEC_CONTROL:
+       __vmwrite_vcpu(field, value);
+       break;
+    }
+
     return 0;
 }
 
@@ -379,11 +439,12 @@ static inline void vmx_stts(void)
 {
     unsigned long cr0;
 
-    __vmread(GUEST_CR0, &cr0);
-    if (!(cr0 & X86_CR0_TS))
+    __vmread_vcpu(GUEST_CR0, &cr0);
+    if (!(cr0 & X86_CR0_TS)) {
         __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS);
+    }
 
-    __vmread(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
     if (!(cr0 & X86_CR0_TS))
        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
@@ -393,7 +454,7 @@ static inline int vmx_paging_enabled(struct vcpu *v)
 {
     unsigned long cr0;
 
-    __vmread(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
     return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
 }
 
index 9c26ef4f97366aa7891145f8e466e322a33cb290..c204df2a5d648a2dd72309603dc9148f7dec18c3 100644 (file)
@@ -74,9 +74,12 @@ struct msr_state{
 struct arch_vmx_struct {
     struct vmcs_struct      *vmcs;  /* VMCS pointer in virtual */
     unsigned long           flags;  /* VMCS flags */
+    unsigned long           cpu_cr0; /* copy of guest CR0 */
+    unsigned long           cpu_shadow_cr0; /* copy of guest read shadow CR0 */
     unsigned long           cpu_cr2; /* save CR2 */
     unsigned long           cpu_cr3;
     unsigned long           cpu_state;
+    unsigned long           cpu_based_exec_control;
     struct msr_state        msr_content;
     void                   *io_bitmap_a, *io_bitmap_b;
 };